package com.chaos.eurekaproducer.aop;

import com.chaos.eurekaproducer.domain.StoreTransactionLog;
import com.chaos.eurekaproducer.service.IStoreTransactionLogService;
import com.chaos.eurekaproducer.service.StoreTransactionLogServiceImpl;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.RequestMapping;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;

/**
 * @author liaopeng
 * @title: AopConfig
 * @projectName eureka-producer
 * @description: TODO
 * @date 2021/1/279:11 下午
 */
@Component
@Aspect
@EnableAspectJAutoProxy
public class AopConfig {


//    @DeclareParents(value="com.chaos.eurekaproducer.service.*", defaultImpl= StoreTransactionLogServiceImpl.class)
//    public static IStoreTransactionLogService ser;

    /**
     * 使用execution表达式定义连接点
     * demo：execution(* com.chaos.eurekaproducer.service.*.*(..))
     */
    @Pointcut("execution(* com.chaos.eurekaproducer.controller.MqController.send(..)) or execution(* insertUsers(..)) ")
    public void pointCut(){}

    @Pointcut("@annotation(com.chaos.eurekaproducer.annotation.ExceptionFlag)")
    public void mqPointCut(){}

    /**
     * 使用within表达式定义连接点
     */
    @Pointcut("within(com.chaos.eurekaproducer.service.*)")
    public void pointCutWithin(){}

    /**
     * 使用args表达式定义连接点，所有参数类型为String的且只有一个参数
     */
    @Pointcut("args(java.lang.String)")
    public void pointCutArgs(){}

    /**
     * 使用@within定义连接点，匹配所有标有Transaction注解的类
     */
    @Pointcut("@within(com.chaos.eurekaproducer.annotation.Transaction)")
    public void pointCutWithin2(){}

    @Pointcut("@target(com.chaos.eurekaproducer.annotation.Transaction)")
    public void pointCutTarget2(){}

//    /**
//     * 前置通知
//     */
//    @Before(value = "pointCut()")
//    public void  before(){
//        System.out.println("before ");
//    }

//    @AfterReturning(value = "pointCut()",returning = "retVal")
//    public void afterReturning(Object retVal){
//        System.out.println("afterReturning "+retVal);
//    }

    @AfterThrowing(value = "mqPointCut()",throwing = "ex")
    public void afterThrowing(JoinPoint joinPoint,Exception ex){
        Class declaringType = joinPoint.getSignature().getDeclaringType();
        RequestMapping classAnnotation = (RequestMapping)declaringType.getAnnotation(RequestMapping.class);
        String[] classValue = classAnnotation.value();

        MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
        String[] methodValue = methodSignature.getMethod().getAnnotation(RequestMapping.class).value();
        Object[] params = joinPoint.getArgs();

        String url = classValue[0]+methodValue[0];
        System.out.println("afterThrowing "+ex.getMessage());

    }

//    @After(value = "pointCut()")
//    public void after(JoinPoint joinPoint){
//        System.out.println(joinPoint.getArgs());
//        System.out.println("after");
//    }
//
//    @Around(value = "pointCut()")
//    public void around(ProceedingJoinPoint point) throws Throwable {
//        System.out.println("start around");
//        Object proceed = point.proceed();
//        System.out.println("end around");
//        System.out.println("around result:"+proceed.toString());
//    }
}
